package pingpongdojo.model;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.eclipse.core.resources.IFile;

public class Game {

	public static enum Objective {
		CODE, TEST
	};

	public static enum Status {
		ACTIVE, COMPLETED
	};

	private UUID id;
	private String name;
	private Set<IFile> testFiles = new HashSet<IFile>();
	private Set<IFile> codeFiles = new HashSet<IFile>();

	private User codePlayer;
	private User testPlayer;
	private Objective currentObjective = Objective.TEST;
	private Date dateLastPlayed = new Date();
	private Status status = Status.ACTIVE;

	public Game() {
	}

	public Game(String name, User codePlayer, User testPlayer) {
		this.id = UUID.randomUUID();
		this.name = name;
		this.codePlayer = codePlayer;
		this.testPlayer = testPlayer;
	}

	public UUID getId() {
		return id;
	}

	public void setId(UUID id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<User> getPlayers() {
		return Arrays.asList(codePlayer, testPlayer);
	}

	public Set<IFile> getTestFiles() {
		return testFiles;
	}

	public Set<IFile> getCodeFiles() {
		return codeFiles;
	}

	public void addFile(IFile newFile) {
		if (newFile.getName().toLowerCase().contains("test")) {
			testFiles.add(newFile);
		} else {
			codeFiles.add(newFile);
		}

		System.out.println("Added: " + newFile.getProjectRelativePath()
				+ " to " + toString());
	}

	public void removeFile(IFile file) {
		testFiles.remove(file);
		codeFiles.remove(file);
	}

	public User getCurrentPlayer() {
		switch (currentObjective) {
		case CODE:
			return codePlayer;
		case TEST:
			return testPlayer;
		}

		return null;
	}

	public User getOtherPlayer() {
		switch (currentObjective) {
		case CODE:
			return testPlayer;
		case TEST:
			return codePlayer;
		}

		return null;
	}

	public User getOtherPlayer(User player) {
		if (codePlayer.equals(player)) {
			return testPlayer;
		}

		return codePlayer;
	}

	public User getCodePlayer() {
		return codePlayer;
	}

	public User getTestPlayer() {
		return testPlayer;
	}

	public Objective getCurrentObjective() {
		return currentObjective;
	}

	public Objective getObjective(User player) {
		if (player.equals(codePlayer)) {
			return Objective.CODE;
		}

		return Objective.TEST;
	}

	public void setCurrentObjective(Objective currentObjective) {
		this.currentObjective = currentObjective;
	}

	public Date getDateLastPlayed() {
		return dateLastPlayed;
	}

	public void setDateLastPlayed(Date dateLastPlayed) {
		this.dateLastPlayed = dateLastPlayed;
	}

	public void setStatus(Status status) {
		this.status = status;
	}

	public Status getStatus() {
		return this.status;
	}

	public void updateDateLastPlayed() {
		Calendar calendar = Calendar.getInstance();
		setDateLastPlayed(calendar.getTime());
	}

	public void end() {
		setStatus(Game.Status.COMPLETED);
		updateDateLastPlayed();
	}

	public void passTurn() {
		Objective objective = getCurrentObjective();
		if (objective == Game.Objective.TEST) {
			setCurrentObjective(Game.Objective.CODE);
		} else {
			setCurrentObjective(Game.Objective.TEST);
		}

		updateDateLastPlayed();
	}

	@Override
	public int hashCode() {
		return id.hashCode();
	}

	@Override
	public boolean equals(Object otherObject) {
		if (!(otherObject instanceof Game)) {
			return false;
		}

		Game otherGame = (Game) otherObject;
		return id.equals(otherGame.getId());
	}

	public String toString() {
		return getName() + " [" + getId() + "]";
	}
}
